﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace iNet.Media
{
	/// <summary>
	/// 表示一個矩形範圍。
	/// </summary>
	/// <typeparam name="T">表示矩形位置的資料型別。</typeparam>
	public struct Rect<T> where T : IComparable<T>
	{
		#region 建構子
		/// <summary>
		/// 初始化 Rect 結構欄位。
		/// </summary>
		/// <param name="left">左緣位置。</param>
		/// <param name="top">上緣位置。</param>
		/// <param name="width">寬度。</param>
		/// <param name="height">高度。</param>
		public Rect(T left, T top, T width, T height)
			: this()
		{
			this.Left = left;
			this.Top = top;
			this.Width = width;
			this.Height = height;
		}
		/// <summary>
		/// 初始化 Rect 結構欄位。
		/// </summary>
		/// <param name="left">左緣位置。</param>
		/// <param name="top">上緣位置。</param>
		/// <param name="size">矩形大小。</param>
		public Rect(T left, T top, Size<T> size)
			: this(left, top, size.Width, size.Height)
		{ }
		#endregion
		#region Equals
		/// <summary>
		/// 確認是否與指定的物件相等。
		/// </summary>
		/// <param name="obj">指定的物件。</param>
		/// <returns>True 表示相等，False 表示不相等。</returns>
		public override bool Equals(object obj)
		{
			if (obj is Rect<T>)
				return this.Equals((Rect<T>)obj);
			return false;
		}
		/// <summary>
		/// 確認是否與指定的 Rect 相等。
		/// </summary>
		/// <param name="rect">指定的 Rect。</param>
		/// <returns>True 表示相等，False 表示不相等。</returns>
		public bool Equals(Rect<T> rect)
		{
			return (this == rect);
		}
		#endregion
		#region Height
		/// <summary>
		/// 取得或設定高度。
		/// </summary>
		public T Height { get; set; }
		#endregion
		#region IsEmpty
		/// <summary>
		/// 取得值以確認是否為空的矩形。
		/// </summary>
		public bool IsEmpty
		{
			get
			{
				return (this.Left.Equals(default(T))
					|| this.Top.Equals(default(T))
					|| this.Width.Equals(default(T))
					|| this.Height.Equals(default(T)));
			}
		}
		#endregion
		#region Left
		/// <summary>
		/// 取得或設定左緣位置。
		/// </summary>
		public T Left { get; set; }
		#endregion
		#region operator ==
		public static bool operator ==(Rect<T> x, Rect<T> y)
		{
			return (x.Left.Equals(y.Left) && x.Top.Equals(y.Top) && x.Width.Equals(y.Width) && x.Height.Equals(y.Height));
		}
		#endregion
		#region operator !=
		public static bool operator !=(Rect<T> x, Rect<T> y)
		{
			return (!x.Left.Equals(y.Left) || !x.Top.Equals(y.Top) || !x.Width.Equals(y.Width) || !x.Height.Equals(y.Height));
		}
		#endregion
		#region Size
		/// <summary>
		/// 取得或設定矩形的大小。
		/// </summary>
		public Size<T> Size
		{
			get
			{
				return new Size<T>(this.Width, this.Height);
			}
			set
			{
				this.Width = value.Width;
				this.Height = value.Height;
			}
		}
		#endregion
		#region Top
		/// <summary>
		/// 取得或設定上緣位置。
		/// </summary>
		public T Top { get; set; }
		#endregion
		#region ToString
		/// <summary>
		/// 取得表示此結構的字串。
		/// </summary>
		/// <returns>表示此結構的字串。</returns>
		public override string ToString()
		{
			return ("(" + this.Left + "," + this.Top + ") " + this.Width + "x" + this.Height);
		}
		#endregion
		#region Width
		/// <summary>
		/// 取得或設定寬度。
		/// </summary>
		public T Width { get; set; }
		#endregion
	}

	/// <summary>
	/// 提供 Rect&lt;T&gt; 相關的延伸方法。
	/// </summary>
	public static class RectExtensions
	{
		#region ToDoubleRect
		/// <summary>
		/// 將指定的 Rect&lt;Int32&gt; 轉換成對應的 Rect&lt;Double&gt;。
		/// </summary>
		/// <param name="rect">指定的 Rect&lt;Int32&gt;。</param>
		/// <returns>對應的 Rect&lt;Double&gt;。</returns>
		public static Rect<double> ToDoubleRect(this Rect<int> rect)
		{
			return new Rect<double>(rect.Left, rect.Top, rect.Width, rect.Height);
		}
		#endregion
		#region ToInt32Rect
		/// <summary>
		/// 將指定的 Rect&lt;Double&gt; 轉換成對應的 Rect&lt;Int32&gt;。
		/// </summary>
		/// <param name="rect">指定的 Rect&lt;Double&gt;。</param>
		/// <returns>對應的 Rect&lt;Int32&gt;。</returns>
		public static Rect<int> ToInt32Rect(this Rect<double> rect)
		{
			return new Rect<int>((int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height);
		}
		#endregion
	}
}
